﻿using System;
using System.Web.Security;
using System.Diagnostics;
using System.Data;
using System.Data.Odbc;
using System.Configuration;

namespace hieunv.Authentication
{
	class AccessMembershipProvider : MembershipProvider
	{
		public const string APPLICATION_NAME = "applicationName";
		public const string APPLICATION_ID = "applicationID";
		public const string ENABLE_PASSWORD_RESET = "enablePasswordReset";
		public const string ENABLE_PASSWORD_RETRIEVAL = "enblePasswordRetrieval";
		public const string MAX_INVALID_PASSWORD_ATTEMPTS = "maxInvalidPasswordAttempts";
		public const string MIN_REQUIRED_NON_ALPHANUMERIC_CHARACTERS = "minRequiredNonAlphanumericCharacters";
		public const string MIN_REQUIRED_PASSWORD_LENGTH = "minRequiredPasswordLength";
		public const string PASSWORD_ATTEMPT_WINDOW = "passwordAttemptWindow";
		public const string PASSWORD_FORMAT = "passwordFormat";
		public const string PASSWORD_STRENGTH_REGULAR_EXPRESSION = "passwordStrengthRegularExpression";
		public const string REQUIRES_QUESTION_AND_ANSWER = "requiresQuestionAndAnswer";
		public const string REQUIRES_UNIQUE_EMAIL = "requiresUniqueEmail";
		public const string CONNECTION_STRING_NAME = "connectionStringName";

		/*public const string DESCRIPTION = "description";*/

		private string _applicationName;
		private string _applicationID;
		private MembershipPasswordFormat _passwordFormat;
		private bool _enablePasswordReset;
		private bool _enablePasswordRetrieval;
		private int _maxInvalidPasswordAttempts;
		private int _minRequiredNonAlphanumericCharacters;
		private int _minRequiredPasswordLength;
		private int _passwordAttemptWindow;
		private string _passwordStrengthRegularExpression;
		private bool _requiresQuestionAndAnswer;
		private bool _requiresUniqueEmail;
		private OdbcConnection _connection;

		public override string ApplicationName
		{
			get
			{
				return this._applicationName;
			}
			set
			{
				this._applicationName = value;
			}
		}

		public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
		{
			try
			{
				name = (string.IsNullOrEmpty(name)) ? "AccessMembershipProvider" : name;
				if (config == null) throw new ArgumentNullException();
// 				if (string.IsNullOrEmpty(config[DESCRIPTION]))
// 				{
// 					config.Remove(DESCRIPTION);
// 					config.Add(DESCRIPTION, "Access Membership Provider");
// 				}
				base.Initialize(name, config);

				this._applicationName = (string.IsNullOrEmpty(config[APPLICATION_NAME])) ? "Access2010" : config[APPLICATION_NAME];
				this._applicationID = (string.IsNullOrEmpty(config[APPLICATION_ID])) ? "" : config[APPLICATION_ID];
				this._enablePasswordReset = (string.IsNullOrEmpty(config[ENABLE_PASSWORD_RESET])) ? true : bool.Parse(config[ENABLE_PASSWORD_RESET]);
				this._enablePasswordRetrieval = (string.IsNullOrEmpty(config[ENABLE_PASSWORD_RETRIEVAL])) ? true : bool.Parse(config[ENABLE_PASSWORD_RETRIEVAL]);
				this._maxInvalidPasswordAttempts = (string.IsNullOrEmpty(config[MAX_INVALID_PASSWORD_ATTEMPTS])) ? 5 : int.Parse(config[MAX_INVALID_PASSWORD_ATTEMPTS]);
				this._minRequiredNonAlphanumericCharacters = (string.IsNullOrEmpty(config[MIN_REQUIRED_NON_ALPHANUMERIC_CHARACTERS])) ? 1 : int.Parse(config[MIN_REQUIRED_NON_ALPHANUMERIC_CHARACTERS]);
				this._minRequiredPasswordLength = (string.IsNullOrEmpty(config[MIN_REQUIRED_PASSWORD_LENGTH])) ? 7 : int.Parse(config[MIN_REQUIRED_PASSWORD_LENGTH]);
				this._passwordAttemptWindow = (string.IsNullOrEmpty(config[PASSWORD_ATTEMPT_WINDOW])) ? 10 : int.Parse(config[PASSWORD_ATTEMPT_WINDOW]);
				if (!string.IsNullOrEmpty(config[PASSWORD_FORMAT]))
				{
					switch (config[PASSWORD_FORMAT])
					{
						case "Clear": this._passwordFormat = MembershipPasswordFormat.Clear; break;
						case "Encrypted": this._passwordFormat = MembershipPasswordFormat.Encrypted; break;
						case "Hashed": this._passwordFormat = MembershipPasswordFormat.Hashed; break;
					}
				}
				else
				{
					this._passwordFormat = MembershipPasswordFormat.Hashed;
				}
				this._passwordStrengthRegularExpression = (string.IsNullOrEmpty(config[PASSWORD_STRENGTH_REGULAR_EXPRESSION])) ? config[PASSWORD_STRENGTH_REGULAR_EXPRESSION] : "";
				this._requiresQuestionAndAnswer = (string.IsNullOrEmpty(config[REQUIRES_QUESTION_AND_ANSWER])) ? false : bool.Parse(config[REQUIRES_QUESTION_AND_ANSWER]);
				this._requiresUniqueEmail = (string.IsNullOrEmpty(config[REQUIRES_UNIQUE_EMAIL])) ? true : bool.Parse(config[REQUIRES_UNIQUE_EMAIL]);
				if (!string.IsNullOrEmpty(config[CONNECTION_STRING_NAME]))
				{
					this._connection = new OdbcConnection(ConfigurationManager.ConnectionStrings[config[CONNECTION_STRING_NAME]].ConnectionString);
				}
			}
			catch (System.Exception ex)
			{
				EventLog.WriteEntry(ex.Source, ex.Message);
			}
		}

		public override bool ChangePassword(string username, string oldPassword, string newPassword)
		{
			throw new NotImplementedException();
		}

		public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
		{
			throw new NotImplementedException();
		}

		public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
		{
			throw new NotImplementedException();
		}

		public override bool DeleteUser(string username, bool deleteAllRelatedData)
		{
			throw new NotImplementedException();
		}

		public override bool EnablePasswordReset
		{
			get
			{
				return this._enablePasswordReset;
			}
		}

		public override bool EnablePasswordRetrieval
		{
			get
			{
				return this._enablePasswordRetrieval;
			}
		}

		public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
		{
			throw new NotImplementedException();
		}

		public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
		{
			throw new NotImplementedException();
		}

		public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
		{
			throw new NotImplementedException();
		}

		public override int GetNumberOfUsersOnline()
		{
			throw new NotImplementedException();
		}

		public override string GetPassword(string username, string answer)
		{
			throw new NotImplementedException();
		}

		public override MembershipUser GetUser(string username, bool userIsOnline)
		{
			throw new NotImplementedException();
		}

		public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
		{
			throw new NotImplementedException();
		}

		public override string GetUserNameByEmail(string email)
		{
			throw new NotImplementedException();
		}

		public override int MaxInvalidPasswordAttempts
		{
			get
			{
				return this._maxInvalidPasswordAttempts;
			}
		}

		public override int MinRequiredNonAlphanumericCharacters
		{
			get
			{
				return this._minRequiredNonAlphanumericCharacters;
			}
		}

		public override int MinRequiredPasswordLength
		{
			get
			{
				return this._minRequiredPasswordLength;
			}
		}

		public override int PasswordAttemptWindow
		{
			get
			{
				return this._passwordAttemptWindow;
			}
		}

		public override MembershipPasswordFormat PasswordFormat
		{
			get
			{
				return this._passwordFormat;
			}
		}

		public override string PasswordStrengthRegularExpression
		{
			get
			{
				return this._passwordStrengthRegularExpression;
			}
		}

		public override bool RequiresQuestionAndAnswer
		{
			get
			{
				return this._requiresQuestionAndAnswer;
			}
		}

		public override bool RequiresUniqueEmail
		{
			get
			{
				return this._requiresUniqueEmail;
			}
		}

		public override string ResetPassword(string username, string answer)
		{
			throw new NotImplementedException();
		}

		public override bool UnlockUser(string userName)
		{
			throw new NotImplementedException();
		}

		public override void UpdateUser(MembershipUser user)
		{
			throw new NotImplementedException();
		}

		public override bool ValidateUser(string username, string password)
		{
			using (this._connection)
			{
				this._connection.Open();
				OdbcCommand command = this._connection.CreateCommand();
				command.CommandText = string.Format("SELECT Password FROM Membership WHERE UserID=(SELECT ID FROM Users WHERE ApplicationID='{0}' AND Username='{1}')", this._applicationID, username);
			}
			throw new NotImplementedException();
		}
	}
}
